package com.gjm.tool.utils;

import cn.hutool.core.util.StrUtil;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 正则校验工具类
 */
public final class RegExpValidatorUtils {
	
	public static final String YEAR_MONTH = "^\\d{4}-((0([1-9]))|(1(0|1|2)))$";
	
	public static final String EMIAIL = "^([\\w-\\.]+)@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.)|(([\\w-]+\\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\\]?)$";
	
	public static final String IPNUM = "(25[0-5]|2[0-4]\\d|[0-1]\\d{2}|[1-9]?\\d)";
	
	public static final String URL = "http(s)?://([\\w-]+\\.)+[\\w-]+(/[\\w- ./?%&=]*)?";
	
	public static final String TELEPHONE = "^(13[0-9]|14[0-9]|15[0-9]|16[0-9]|17[0-9]|18[0-9]|19[0-9])\\d{8}$";
	
	public static final String PASSWORD = "^\\S{6,18}$";
	
	public static final String POSTCODE = "^\\d{6}$";
	
	public static final String IDCARD = "^[1-9][0-9]{5}(19|20)[0-9]{2}((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|30|31)|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|[1-2][0-9]))[0-9]{3}([0-9]|x|X)$";
	
	public static final String DECIMAL = "[-+]{0,1}\\d+\\.\\d*|[-+]{0,1}\\d*\\.\\d+"; //小数
	
	public static final String MONTH = "^(0?[[1-9]|1[0-2])$";
	
	public static final String DAY = "^((0?[1-9])|((1|2)[0-9])|30|31)$";
	
	public static final String DATE = "^((((1[6-9]|[2-9]\\d)\\d{2})-(0?[13578]|1[02])-(0?[1-9]|[12]\\d|3[01]))|(((1[6-9]|[2-9]\\d)\\d{2})-(0?[13456789]|1[012])-(0?[1-9]|[12]\\d|30))|(((1[6-9]|[2-9]\\d)\\d{2})-0?2-(0?[1-9]|1\\d|2[0-8]))|(((1[6-9]|[2-9]\\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))-0?2-29-)) (20|21|22|23|[0-1]?\\d):[0-5]?\\d:[0-5]?\\d$";

	public static final String DATE_YMD = "^((((1[6-9]|[2-9]\\d)\\d{2})-(0?[13578]|1[02])-(0?[1-9]|[12]\\d|3[01]))|(((1[6-9]|[2-9]\\d)\\d{2})-(0?[13456789]|1[012])-(0?[1-9]|[12]\\d|30))|(((1[6-9]|[2-9]\\d)\\d{2})-0?2-(0?[1-9]|1\\d|2[0-8]))|(((1[6-9]|[2-9]\\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))-0?2-29-))$";

	public static final String DATE_HM = "(20|21|22|23|[0-1]?\\d):[0-5]?\\d";

	public static final String NUMBER = "^[0-9]*$";
	
	public static final String INTNUMBER = "^\\+?[1-9][0-9]*$";
	
	public static final String UPPERCASE = "^[A-Z]+$";
	
	public static final String LOWERCASE = "^[a-z]+$";
	
	public static final String LETTER = "^[A-Za-z]+$";
	
	public static final String CHINESE = "^[\u4e00-\u9fa5],{0,}$";
	
	public static final String LENGTH = "^.{8,}$";
	
	public static final String TAXNUM = "^([A-Za-z0-9]{15})|([A-Za-z0-9]{18})|([A-Za-z0-9]{20})$";

	public static final String GOODS_NAME = "^.{0,50}$";

    public static final String CHINA_TELEPHONE = "^(1)\\d{10}$";

    public static final String WORK_GROUP_NAME = "^[A-Za-z0-9\u4e00-\u9fa5]{1,25}$";

    public static final String DOMAIN = "^(?=^.{3,255}$)[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+$";

    public static final String NUMBERS = "(\\d+\\.\\d+)|\\d+";

    /**
     * @param regex 正则表达式字符串
     * @param str   要匹配的字符串
     * @return 如果str 符合 regex的正则表达式格式,返回true, 否则返回 false;
     */
    public static boolean match(String regex, String str) {
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(str);
        return matcher.matches();
    }

    /**
     * @param regex 正则表达式字符串
     * @param str   要匹配的字符串
     * @return;
     */
    public static List<String> find(String regex, String str) {
        List<String> list = new ArrayList<>();
        if (StrUtil.isBlank(regex) || StrUtil.isBlank(str)) {
            return list;
        }
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(str);
        while (matcher.find()) {
            list.add(matcher.group());
        }
        return list;
    }
	
    /**
     * 验证纳税人识别号，15,18,20位
     *
     * @param str
     * @return 如果是符合的字符串, 返回 <b>true </b>,否则为 <b>false </b>
     */
    public static boolean isTaxNum(String str) {
        return match(TAXNUM, str);
    }
    
    /**
     * 验证邮箱
     *
     * @param str
     * @return 如果是符合的字符串, 返回 <b>true </b>,否则为 <b>false </b>
     */
    public static boolean isEmail(String str) {
    	return match(EMIAIL, str);
    }

    public static boolean isPeriod(String str) {
        return match(YEAR_MONTH, str);
    }

    /**
     * 验证IP地址
     *
     * @param str
     * @return 如果是符合格式的字符串, 返回 <b>true </b>,否则为 <b>false </b>
     */
    public static boolean isIP(String str) {
        String regex = "^" + IPNUM + "\\." + IPNUM + "\\." + IPNUM + "\\." + IPNUM + "$";
        return match(regex, str);
    }

    /**
     * 验证网址Url
     *
     * @param str
     * @return 如果是符合格式的字符串, 返回 <b>true </b>,否则为 <b>false </b>
     */
    public static boolean IsUrl(String str) {
        return match(URL, str);
    }

    /**
     * 验证手机号码
     *
     * @param str
     * @return 如果是符合格式的字符串, 返回 <b>true </b>,否则为 <b>false </b>
     */
    public static boolean IsTelephone(String str) {
        return match(TELEPHONE, str);
    }

    /**
     * 验证输入密码条件(字符与数据同时出现)
     *
     * @param str
     * @return 如果是符合格式的字符串, 返回 <b>true </b>,否则为 <b>false </b>
     */
    public static boolean IsPassword(String str) {
        return match(PASSWORD, str);
    }

    /**
     * 验证输入邮政编号
     *
     * @param str
     * @return 如果是符合格式的字符串, 返回 <b>true </b>,否则为 <b>false </b>
     */
    public static boolean IsPostalcode(String str) {
        return match(POSTCODE, str);
    }

    /**
     * 验证输入身份证号
     *
     * @param str
     * @return 如果是符合格式的字符串, 返回 <b>true </b>,否则为 <b>false </b>
     */
    public static boolean IsIDcard(String str) {
        return match(IDCARD, str);
    }

    /**
     *
     * @param str
     * @return 如果是符合格式的字符串, 返回 <b>true </b>,否则为 <b>false </b>
     */
    public static boolean IsDecimal(String str) {
        return match(DECIMAL, str);
    }

    /**
     * 验证输入一年的12个月
     *
     * @param str
     * @return 如果是符合格式的字符串, 返回 <b>true </b>,否则为 <b>false </b>
     */
    public static boolean IsMonth(String str) {
        return match(MONTH, str);
    }

    /**
     * 验证输入一个月的31天
     *
     * @param str
     * @return 如果是符合格式的字符串, 返回 <b>true </b>,否则为 <b>false </b>
     */
    public static boolean IsDay(String str) {
        return match(DAY, str);
    }

    /**
     * 验证日期时间
     *
     * @param str
     * @return 如果是符合网址格式的字符串, 返回 <b>true </b>,否则为 <b>false </b>
     */
    public static boolean isDate(String str) {
        return match(DATE, str);
    }

    /**
     * 验证日期时间- 2022-11-12 类型
     *
     * @param str
     * @return 如果是符合网址格式的字符串, 返回 <b>true </b>,否则为 <b>false </b>
     */
    public static boolean isDateYMD(String str) {
        return match(DATE_YMD, str);
    }

    /**
     * 验证数字输入
     *
     * @param str
     * @return 如果是符合格式的字符串, 返回 <b>true </b>,否则为 <b>false </b>
     */
    public static boolean IsNumber(String str) {
        return match(NUMBER, str);
    }

    /**
     * 验证非零的正整数
     *
     * @param str
     * @return 如果是符合格式的字符串, 返回 <b>true </b>,否则为 <b>false </b>
     */
    public static boolean IsIntNumber(String str) {
        return match(INTNUMBER, str);
    }

    /**
     * 验证大写字母
     *
     * @param str
     * @return 如果是符合格式的字符串, 返回 <b>true </b>,否则为 <b>false </b>
     */
    public static boolean IsUpChar(String str) {
        return match(UPPERCASE, str);
    }

    /**
     * 验证小写字母
     *
     * @param str
     * @return 如果是符合格式的字符串, 返回 <b>true </b>,否则为 <b>false </b>
     */
    public static boolean IsLowChar(String str) {
        return match(LOWERCASE, str);
    }

    /**
     * 验证验证输入字母
     *
     * @param str
     * @return 如果是符合格式的字符串, 返回 <b>true </b>,否则为 <b>false </b>
     */
    public static boolean IsLetter(String str) {
        return match(LETTER, str);
    }

    /**
     * 验证验证输入汉字
     *
     * @param str
     * @return 如果是符合格式的字符串, 返回 <b>true </b>,否则为 <b>false </b>
     */
    public static boolean IsChinese(String str) {
        return match(CHINESE, str);
    }

    /**
     * 验证验证输入字符串
     *
     * @param str
     * @return 如果是符合格式的字符串, 返回 <b>true </b>,否则为 <b>false </b>
     */
    public static boolean IsLength(String str) {
        return match(LENGTH, str);
    }

    /**
     * 验证商品名称
     *
     * @param str
     * @return 如果是符合格式的字符串, 返回 <b>true </b>,否则为 <b>false </b>
     */
    public static boolean IsGoodsName(String str) {
        return match(GOODS_NAME, str);
    }

    /**
     * 验证中国手机号码
     *
     * @param str
     * @return 如果是符合格式的字符串, 返回 <b>true </b>,否则为 <b>false </b>
     */
    public static boolean IsChinaPhone(String str) {
        return match(CHINA_TELEPHONE, str);
    }

    /**
     * 是否全是数字
     *
     * @param str
     * @return 如果是符合格式的字符串, 返回 <b>true </b>,否则为 <b>false </b>
     */
    public static boolean isNumber(String str) {
        return match("[0-9]{5}", str);
    }

    /**
     * 提取数字
     * @param str
     * @return
     */
    public static List<String> getNumber(String str){
        return find(NUMBERS,str);
    }

    /**
     * 提取日期时间- 15:30 类型
     *
     * @param str
     * @return 如果是符合网址格式的字符串, 返回 <b>true </b>,否则为 <b>false </b>
     */
    public static List<String> getDateHM(String str) {
        return find(DATE_HM, str);
    }

    public static void main(String[] args) {
        String str = "PING fc02::192.168.145.0(fc02::c0a8:9100) 56 data bytes\n" +
                "\n" +
                "--- fc02::192.168.145.0 ping statistics ---\n" +
                "1 packets transmitted, 0 received, 100% packet loss, time 0ms";
        String regex = "\\((.*?)\\)";
        List<String> list = new ArrayList<>();
        if (StrUtil.isNotBlank(regex) && StrUtil.isNotBlank(str)) {
            Pattern pattern = Pattern.compile(regex);
            Matcher matcher = pattern.matcher(str);
            while (matcher.find()) {
                list.add(matcher.group(1));
            }
        }


        for (String s : list) {
            System.out.println(s);
        }
    }
}